/**
 * @brief HScb is a safety board for the MAX Cabinet
 */
#pragma once
#include "rtdev/safetyboard/scbitf.h"
#include "rtdev/safetyboard/safetydev.h"
#include "rtdev/safetyboard/cab.h"
#include "rtdev/safetyboard/iodev.h"
#include "rtdev/safetyboard/powerdev.h"

namespace rtdev {
class HScb;

/**
 * @brief MAX的机柜本体电源监控,仅一路电源
 */
class HScbRobotPower : public ScbRobPowerItf
{
public:
    HScbRobotPower();
    int set_power(bool power, int robid = -1) override;
    double get_power(int robid) override;
    double get_voltage(int robid) override;
    double get_current(int robid) override;

    struct Feedback
    {
        bool is_cmd_power_on;  //指令是否通电
        double voltage;        //本体电压
        double current;        //本体电流
        double power;          //本体功率
    };
    Feedback feedbacks;
    HScb* scb;
};
class HScbSafetySignal : public rtdev::ScbSafetySignalItf
{
public:
    HScbSafetySignal();
    int get_ei_stat(bool dual_chn[2], bool* has_fault) override;
    int get_ext_ei_stat(bool dual_chn[2], bool* has_fault) override;
    int get_si_stat(bool dual_chn[2], bool* has_fault) override;
    int set_tcp_offset(float x, float y, float z) override;

    bool ei[2], ei_fault;
    bool ext_ei[2], ext_ei_fault;
    bool si[2], si_fault;
};

/**
 * @brief MAX的机柜信息监控
 */
class HScbCab : public rtdev::DefaultCab
{
public:
    HScbCab();

    int get_id();
    int set_id(uint32_t id);
    int get_stuck_voltage(bool is_act) override { return 0; }   //该机柜没有该参数
    int set_stuck_voltage(int voltage) override { return -1; }  //该机柜没有该参数
    int set_power_supply(int val) override { return -1; }       //该机柜没有该参数
    int get_power_supply() override { return 380; }             //该机柜固定为380V

    int32_t cmd_cab_id, act_cab_id;
};

class HScb : public SafetyBoardItf
{
public:
    HScb();
    const char* name() override;
    int init(void* cfgfile, int sim) override;
    int boot() override;

    ScbRobPowerItf* rob_power() override { return &rob; }
    rtdev::ScbCabItf* cab() override { return &cab_; }
    rtdev::ScbSafetySignalItf* safety_signal() override { return &safedev; }
    rtdev::ScbIOItf* io() override { return &iodev; }

    int set_send_data(int busid) override;
    int get_recv_data(int busid) override;

    int get_sdo_blocking(uint32_t objid, void* data, int s, int retry = 3) override;
    int set_sdo_blocking(uint32_t objid, void* data, size_t s, void* readback = nullptr, int retry = 3) override;

private:
    rtdev::HScbSafetySignal safedev;
    rtdev::NoIoDev iodev;
    HScbRobotPower rob;
    HScbCab cab_;

    std::shared_ptr<rtbus::RtCommuItf> bus_;
};

}  // namespace rtdev
